﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AutomationMLMapperMain.xaml.cs" >
//   J. Prinz
// </copyright>
// <summary>
//   Interaction logic for AutomationMLMapperMain.xaml
//  
// The Software uses the AvalonDock Library from Adolfo Marinucci. <see href="http://avalondock.codeplex.com/">
// Please notice the following License Conditions:
// --------------------------------------------------------------------------------------------------------------------
// BSD License (BSD)
// Copyright (c) 2007-2012, Adolfo Marinucci
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided with the distribution.
//
// Neither the name of Adolfo Marinucci nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --------------------------------------------------------------------------------------------------------------------
// Many of the icons are created, based on the Multipurpose Alphabet Icons Set made by Supratim Nayak 
// Please Respect Copyrights. <see href="http://www.iconarchive.com/show/multipurpose-alphabet-icons-by-hydrattz.html">
// --------------------------------------------------------------------------------------------------------------------
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace AutomationMLMapper
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;
    using System.Windows.Media.Imaging;
    using System.Xml;
    using AvalonDock.Layout;
    using AvalonDock.Layout.Serialization;
    using AutomationMLMapper.Properties;
    using AutomationMLMapper.ViewModels.SystemViewModels;
    using AvalonDock;
    using AutomationMLMapper.ViewModels.PaneViewModels;
    using System.Collections.Generic;
    using AutomationMLMapper.Utilities;
    using AutomationMLMapper.Controls.MarkupExtensions;

    /// <summary>
    /// Interaction logic for AutomationMLMapperMain.xaml which is the main view of the application
    /// </summary>
    public partial class AutomationMLMapperMain: INotifyPropertyChanged
    {
        #region Fields

        public static AutomationMLMapperMain MainView;
        /// <summary>
        /// The main view model.
        /// </summary>
        private readonly AutomationMLMapperViewModel viewModel;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="AutomationMLMapperMain"/> class. 
        /// </summary>
        public AutomationMLMapperMain()
        {
            this.viewModel = new AutomationMLMapperViewModel { MainView = this };
            this.DataContext = this.viewModel;
            this.InitializeComponent();
                     

            AutomationMLMapperViewModel.MainViewModel = this.viewModel;
            MainView = this;
        }       

        #endregion
                    
        #region Methods

        /// <summary>
        /// Close handler for the MainView stores settings of window properties and quick access toolbar
        /// </summary>
        /// <param name="e">
        /// Cancel Event Argument
        /// </param>
        protected override void OnClosing(CancelEventArgs e)
        {
            var buttons = new QuickAccessToolbarButtonCollection();
           
            Settings.Default.FirstRun = false;
            Settings.Default.WindowSize = new Size(this.Width, this.Height);
            Settings.Default.WindowLocation = new Point(this.Left, this.Top);
            Settings.Default.WindowState = this.WindowState;
            Settings.Default.Save();

            // don't serialize Panes with Content Models, because those Models depend on ModelData
            foreach (var document in this.dockManager.Layout.Descendents().OfType<LayoutAnchorable>().ToList())
            {
                if (document.Content is PaneViewModel)
                    document.Close();
            }

            var layoutSerializer = new XmlLayoutSerializer(this.dockManager);
            layoutSerializer.Serialize(@".\AutomationMLMapperDockLayout.config");

            base.OnClosing(e);
        }
           
        /// <summary>
        /// Initialization Handler of the MainView restores settings of window properties and quick access toolbar
        /// </summary>
        /// <param name="e">
        /// event argument
        /// </param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            if (!Settings.Default.FirstRun)
            {
                this.Width = Settings.Default.WindowSize.Width;
                this.Height = Settings.Default.WindowSize.Height;
                const double Epsilon = 0.00000000000001;
                if (Math.Abs(this.Width - 0) < Epsilon)
                {
                    this.Width = 1024;
                }

                if (Math.Abs(this.Height - 0) < Epsilon)
                {
                    this.Height = 640;
                }

                this.Left = Settings.Default.WindowLocation.X;
                this.Top = Settings.Default.WindowLocation.Y;
                this.WindowState = Settings.Default.WindowState;
                
                
                if (File.Exists(@".\AutomationMLMapperDockLayout.config"))
                {
                    var layoutSerializer = new XmlLayoutSerializer(this.dockManager);
                    ////LayoutSerializationCallback should anyway be handled to attach contents
                    ////not currently loaded
                    layoutSerializer.LayoutSerializationCallback += (sender, eventArg) =>
                    {
                        if (eventArg.Model.ContentId == "SourceClassList")
                        {
                            eventArg.Content = new Controls.SystemUnitClassListControl() { DataContext = viewModel.Export };
                            eventArg.Model.IconSource = new ImageResolutionExtension("SC.ico", 16).GetResolutionImage();
                        }
                        else if (eventArg.Model.ContentId == "SourceRoleClassList")
                        {
                            eventArg.Content = new Controls.RoleClassListControl() { DataContext = viewModel.Export };
                            eventArg.Model.IconSource = new ImageResolutionExtension("RC.ico", 16).GetResolutionImage();
                        }
                        else if (eventArg.Model.ContentId == "TargetClassList")
                        {
                            eventArg.Content = new Controls.SystemUnitClassListControl() { DataContext = viewModel.Import };
                            eventArg.Model.IconSource = new ImageResolutionExtension( "SC.ico",16).GetResolutionImage();
                        }
                        else if (eventArg.Model.ContentId == "TargetRoleClassList")
                        {
                            eventArg.Content = new Controls.RoleClassListControl() { DataContext = viewModel.Import };
                            eventArg.Model.IconSource = new ImageResolutionExtension("RC.ico", 16).GetResolutionImage();
                        }
                        else if (eventArg.Model.ContentId == "InstanceBuilder")
                        {
                            eventArg.Content = new Controls.InstanceListControl() { DataContext = viewModel.Export };
                            eventArg.Model.IconSource = new ImageResolutionExtension("IE.ico", 16).GetResolutionImage();
                        }
                        else if (eventArg.Model.ContentId == "ImportSimulator")
                        {
                            eventArg.Content = new Controls.ImporterControl() { DataContext = viewModel.Import };
                            eventArg.Model.IconSource = Utils.PackImage("IEE.ico");
                        }
                    };
                    layoutSerializer.Deserialize(@".\AutomationMLMapperDockLayout.config");
                }

                else
                {
                    var layoutSerializer = new XmlLayoutSerializer(this.dockManager);
                    layoutSerializer.Serialize(@".\AutomationMLMapperDockInitialLayout.config");
                }
            }

            foreach (var document in this.dockManager.Layout.Descendents().OfType<LayoutAnchorable>())
            {
                document.IsVisibleChanged += document_IsVisibleChanged;
            }

            UpdateHiddenWindowProperty();
        }

        void document_IsVisibleChanged(object sender, EventArgs e)
        {
            UpdateHiddenWindowProperty();
        }

        /// <summary>
        /// update the active Object of the MainViewModel <see cref="AutomationMLMapperViewModel"/>
        /// </summary>
        /// <param name="sender">
        /// Tab-Control in the Main View
        /// </param>
        /// <param name="e">
        /// Selction changed event argument
        /// </param>
        private void TabControlSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sender is TabControl && (sender as TabControl).SelectedContent is UserControl)
            {
                var userControl = (sender as TabControl).SelectedContent as UserControl;
                if (userControl != null)
                {
                    this.viewModel.ActiveSystem = userControl.DataContext as SystemViewModel;
                }
            }
        }

        #endregion
        
        #region Public Properties
        
        /// <summary>
        /// Windows which are closed but are still under control of the docking manager
        /// </summary>
        public IEnumerable<LayoutAnchorable> HiddenWindows
        {
            get
            { 
                return this.dockManager.Layout.Descendents().OfType<LayoutAnchorable>().Where
                    (w => w.IsHidden);
            }
        }

        /// <summary>
        /// true, if <see cref="HiddenWindows"/> exist
        /// </summary>
        public bool HiddenWindowsExist
        {
            get
            {
                return this.dockManager.Layout.Descendents().OfType<LayoutAnchorable>().Any
                    (w => w.IsHidden);
            }
        }

        #endregion

        #region Public Methods
        
        /// <summary>
        /// show a hidden document (reopen)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ShowDocument(object sender, RoutedEventArgs e)
        {
            if (sender is MenuItem)
            {
                LayoutAnchorable document = (sender as MenuItem).Tag as LayoutAnchorable;
                if (document != null)
                {
                    document.Show();                    
                    OnNotifyPropertyChanged("HiddenWindowsExist");
                    OnNotifyPropertyChanged("HiddenWindows");

                    document.IsActive = true;
                    this.Focus();
                }
            }
        }

        /// <summary>
        ///  Refresh all Hidden Windows Properties
        /// </summary>
        internal void UpdateHiddenWindowProperty()
        {
            OnNotifyPropertyChanged("HiddenWindows");
            OnNotifyPropertyChanged("HiddenWindowsExist"); 
        }
        #endregion

        #region INotifyPropertyChanged
       
        /// <summary>
        /// Property change event
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// PropertyChange Notification method
        /// </summary>
        /// <param name="propertyName">
        /// The property Name.
        /// </param>
        protected void OnNotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
        
      
        private void RibbonMenuItem_Click(object sender, RoutedEventArgs e)
        {
            foreach (var document in this.HiddenWindows.ToList())
            {
                document.Show();
            }

            var layoutSerializer = new XmlLayoutSerializer(this.dockManager);
            layoutSerializer.Deserialize(@".\AutomationMLMapperDockInitialLayout.config");

            foreach (var document in this.dockManager.Layout.Descendents().OfType<LayoutAnchorable>())
            {
                document.IsVisibleChanged -= document_IsVisibleChanged;
                document.IsVisibleChanged += document_IsVisibleChanged;
            }
        }
    }
}